package com.english.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.english.config.WechatPayConfig;
import com.english.entity.StudentRecharge;
import com.english.entity.User;
import com.english.mapper.StudentRechargeMapper;
import com.english.mapper.UserMapper;
import com.english.service.WechatPayService;
import com.english.utils.WechatPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信支付服务实现类
 */
@Slf4j
@Service
public class WechatPayServiceImpl implements WechatPayService {

    @Autowired
    private WechatPayConfig wechatPayConfig;
    
    @Autowired
    private StudentRechargeMapper studentRechargeMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public Map<String, Object> createPayment(Long userId, BigDecimal amount, String description) {
        try {
            // 1. 获取用户信息，获取openid
            User user = userMapper.selectById(userId);
            if (user == null || user.getWechatId() == null || user.getWechatId().isEmpty()) {
                throw new RuntimeException("用户信息不完整，无法进行支付");
            }
            
            // 2. 生成订单号
            String orderNo = WechatPayUtil.generateOrderNo();
            
            // 3. 创建充值记录
            StudentRecharge recharge = new StudentRecharge();
            recharge.setOrderNo(orderNo);
            recharge.setUserId(userId);
            recharge.setAmount(amount);
            recharge.setNotes(description);
            recharge.setIsProcessed(0); // 未处理
            recharge.setPaymentStatus(0); // 待支付
            recharge.setRechargeTime(new Date());
            recharge.setUpdateTime(new Date());
            studentRechargeMapper.insert(recharge);
            
            // 4. 准备微信支付参数
            Map<String, String> params = new HashMap<>();
            params.put("appid", wechatPayConfig.getAppId());
            params.put("mch_id", wechatPayConfig.getMchId());
            params.put("nonce_str", WechatPayUtil.generateNonceStr());
            // 修复：避免中文字符编码问题，或确保正确编码
            String bodyParam = description;
            if (bodyParam.contains("中文") || bodyParam.matches(".*[\\u4e00-\\u9fa5].*")) {
                // 如果包含中文，先尝试简化描述
                bodyParam = "Course Recharge - " + amount + " CNY";
            }
            params.put("body", bodyParam);
            params.put("out_trade_no", orderNo);
            params.put("total_fee", String.valueOf(amount.multiply(new BigDecimal("100")).intValue())); // 转换为分
            params.put("spbill_create_ip", "127.0.0.1");
            params.put("notify_url", wechatPayConfig.getNotifyUrl());
            params.put("trade_type", "JSAPI");
            params.put("openid", user.getWechatId()); // 使用真实的用户openid
            params.put("sign_type", "MD5"); // 添加签名类型
            
            // 5. 生成签名
            String sign = WechatPayUtil.generateSign(params, wechatPayConfig.getApiKey());
            params.put("sign", sign);
            
            // 6. 调用微信统一下单接口
            String xmlData = WechatPayUtil.mapToXml(params);
            log.info("微信支付请求参数: {}", xmlData);
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_XML);
            HttpEntity<String> entity = new HttpEntity<>(xmlData, headers);
            
            ResponseEntity<String> response = restTemplate.postForEntity(
                wechatPayConfig.getUnifiedOrderUrl(), entity, String.class);
            
            log.info("微信支付响应状态: {}", response.getStatusCode());
            log.info("微信支付响应内容: {}", response.getBody());
            
            // 7. 解析响应
            Map<String, String> result = WechatPayUtil.xmlToMap(response.getBody());
            log.info("解析后的响应Map: {}", result);
            
            if ("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("result_code"))) {
                // 8. 生成小程序支付参数
                String prepayId = result.get("prepay_id");
                String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
                String nonceStr = WechatPayUtil.generateNonceStr();
                
                Map<String, String> payParams = new HashMap<>();
                payParams.put("appId", wechatPayConfig.getAppId());
                payParams.put("timeStamp", timeStamp);
                payParams.put("nonceStr", nonceStr);
                payParams.put("package", "prepay_id=" + prepayId);
                payParams.put("signType", "MD5");
                
                String paySign = WechatPayUtil.generateSign(payParams, wechatPayConfig.getApiKey());
                
                Map<String, Object> paymentResult = new HashMap<>();
                paymentResult.put("appId", wechatPayConfig.getAppId());
                paymentResult.put("timeStamp", timeStamp);
                paymentResult.put("nonceStr", nonceStr);
                paymentResult.put("package", "prepay_id=" + prepayId);
                paymentResult.put("signType", "MD5");
                paymentResult.put("paySign", paySign);
                paymentResult.put("orderNo", orderNo);
                
                return paymentResult;
            } else {
                log.error("微信支付下单失败: {}", result);
                String errorMsg = result.get("err_code_des");
                if (errorMsg == null) {
                    errorMsg = result.get("return_msg");
                }
                throw new RuntimeException("支付下单失败: " + errorMsg);
            }
            
        } catch (Exception e) {
            log.error("创建支付订单失败", e);
            throw new RuntimeException("创建支付订单失败: " + e.getMessage());
        }
    }

    @Override
    public boolean handlePaymentNotify(String notifyData) {
        try {
            // 1. 解析回调数据
            Map<String, String> result = WechatPayUtil.xmlToMap(notifyData);
            
            // 2. 验证签名
            if (!WechatPayUtil.verifySign(result, wechatPayConfig.getApiKey())) {
                log.error("微信支付回调签名验证失败");
                return false;
            }
            
            // 3. 验证支付结果
            if ("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("result_code"))) {
                String orderNo = result.get("out_trade_no");
                String transactionId = result.get("transaction_id");
                
                // 4. 更新订单状态
                LambdaQueryWrapper<StudentRecharge> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(StudentRecharge::getOrderNo, orderNo);
                StudentRecharge recharge = studentRechargeMapper.selectOne(queryWrapper);
                
                if (recharge != null && recharge.getPaymentStatus() == 0) {
                    recharge.setPaymentStatus(1); // 支付成功
                    recharge.setWechatOrderNo(transactionId);
                    recharge.setUpdateTime(new Date());
                    studentRechargeMapper.updateById(recharge);
                    
                    log.info("支付成功回调处理完成，订单号: {}, 微信订单号: {}", orderNo, transactionId);
                    return true;
                }
            }
            
        } catch (Exception e) {
            log.error("处理支付回调失败", e);
        }
        
        return false;
    }

    @Override
    public Map<String, Object> queryOrder(String orderNo) {
        try {
            Map<String, String> params = new HashMap<>();
            params.put("appid", wechatPayConfig.getAppId());
            params.put("mch_id", wechatPayConfig.getMchId());
            params.put("out_trade_no", orderNo);
            params.put("nonce_str", WechatPayUtil.generateNonceStr());
            
            String sign = WechatPayUtil.generateSign(params, wechatPayConfig.getApiKey());
            params.put("sign", sign);
            
            String xmlData = WechatPayUtil.mapToXml(params);
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_XML);
            HttpEntity<String> entity = new HttpEntity<>(xmlData, headers);
            
            ResponseEntity<String> response = restTemplate.postForEntity(
                wechatPayConfig.getOrderQueryUrl(), entity, String.class);
            
            Map<String, String> result = WechatPayUtil.xmlToMap(response.getBody());
            
            Map<String, Object> orderInfo = new HashMap<>();
            orderInfo.put("return_code", result.get("return_code"));
            orderInfo.put("result_code", result.get("result_code"));
            orderInfo.put("trade_state", result.get("trade_state"));
            orderInfo.put("out_trade_no", result.get("out_trade_no"));
            orderInfo.put("transaction_id", result.get("transaction_id"));
            
            return orderInfo;
            
        } catch (Exception e) {
            log.error("查询订单失败", e);
            throw new RuntimeException("查询订单失败: " + e.getMessage());
        }
    }

    @Override
    public boolean refund(String orderNo, BigDecimal refundAmount, String reason) {
        // 退款功能实现，需要使用证书进行请求
        // 这里先返回false，表示暂不支持
        log.warn("退款功能暂未实现");
        return false;
    }
} 